package com.datagateway.controller;

import com.datagateway.component.PerformanceOptimizer;
import com.datagateway.component.StressTestRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 性能测试控制器
 * 提供性能测试和压力测试的API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/api/performance")
public class PerformanceTestController {

    @Autowired
    private PerformanceOptimizer performanceOptimizer;

    @Autowired
    private StressTestRunner stressTestRunner;

    /**
     * 获取当前性能指标
     * 
     * @return 当前性能指标
     */
    @GetMapping("/metrics")
    public PerformanceOptimizer.PerformanceMetrics getCurrentPerformanceMetrics() {
        return performanceOptimizer.getCurrentPerformanceMetrics();
    }

    /**
     * 获取性能统计信息
     * 
     * @return 性能统计信息
     */
    @GetMapping("/statistics")
    public PerformanceOptimizer.PerformanceStatistics getPerformanceStatistics() {
        return performanceOptimizer.getPerformanceStatistics();
    }

    /**
     * 执行轻量级压力测试
     * 
     * @return 测试结果
     */
    @PostMapping("/stress-test/light")
    public Map<String, Object> runLightStressTest() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 轻量级测试配置：5个线程，30秒，每秒100条消息
            StressTestRunner.StressTestConfig config = new StressTestRunner.StressTestConfig(
                5, 30, 1000, 100, 60
            );
            
            StressTestRunner.StressTestResult testResult = stressTestRunner.runStressTest(config);
            
            result.put("success", true);
            result.put("testResult", testResult);
            result.put("message", "轻量级压力测试完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "轻量级压力测试失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 执行中等强度压力测试
     * 
     * @return 测试结果
     */
    @PostMapping("/stress-test/medium")
    public Map<String, Object> runMediumStressTest() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 中等强度测试配置：10个线程，60秒，每秒200条消息
            StressTestRunner.StressTestConfig config = new StressTestRunner.StressTestConfig(
                10, 60, 2000, 200, 120
            );
            
            StressTestRunner.StressTestResult testResult = stressTestRunner.runStressTest(config);
            
            result.put("success", true);
            result.put("testResult", testResult);
            result.put("message", "中等强度压力测试完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "中等强度压力测试失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 执行高强度压力测试
     * 
     * @return 测试结果
     */
    @PostMapping("/stress-test/heavy")
    public Map<String, Object> runHeavyStressTest() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 高强度测试配置：20个线程，120秒，每秒500条消息
            StressTestRunner.StressTestConfig config = new StressTestRunner.StressTestConfig(
                20, 120, 5000, 500, 180
            );
            
            StressTestRunner.StressTestResult testResult = stressTestRunner.runStressTest(config);
            
            result.put("success", true);
            result.put("testResult", testResult);
            result.put("message", "高强度压力测试完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "高强度压力测试失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 执行自定义压力测试
     * 
     * @param request 测试配置请求
     * @return 测试结果
     */
    @PostMapping("/stress-test/custom")
    public Map<String, Object> runCustomStressTest(@RequestBody StressTestRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 验证请求参数
            if (request.getThreadCount() <= 0 || request.getThreadCount() > 100) {
                result.put("success", false);
                result.put("message", "线程数量必须在1-100之间");
                return result;
            }
            
            if (request.getDurationSeconds() <= 0 || request.getDurationSeconds() > 600) {
                result.put("success", false);
                result.put("message", "测试时长必须在1-600秒之间");
                return result;
            }
            
            // 创建测试配置
            StressTestRunner.StressTestConfig config = new StressTestRunner.StressTestConfig(
                request.getThreadCount(),
                request.getDurationSeconds(),
                request.getMaxMessagesPerThread(),
                request.getMessagesPerSecond(),
                request.getTimeoutSeconds()
            );
            
            StressTestRunner.StressTestResult testResult = stressTestRunner.runStressTest(config);
            
            result.put("success", true);
            result.put("testResult", testResult);
            result.put("message", "自定义压力测试完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "自定义压力测试失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 执行性能基准测试
     * 
     * @param request 基准测试配置请求
     * @return 基准测试结果
     */
    @PostMapping("/benchmark")
    public Map<String, Object> runBenchmarkTest(@RequestBody BenchmarkTestRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 创建基准测试配置
            StressTestRunner.BenchmarkConfig config = new StressTestRunner.BenchmarkConfig(
                request.getBenchmarkName(),
                request.getThreadCount(),
                request.getDurationSeconds(),
                request.getMaxMessagesPerThread(),
                request.getMessagesPerSecond(),
                request.getTimeoutSeconds()
            );
            
            StressTestRunner.BenchmarkResult benchmarkResult = stressTestRunner.runBenchmarkTest(config);
            
            result.put("success", true);
            result.put("benchmarkResult", benchmarkResult);
            result.put("message", "性能基准测试完成");
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "性能基准测试失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 获取性能优化建议
     * 
     * @return 优化建议
     */
    @GetMapping("/optimization-suggestions")
    public Map<String, Object> getOptimizationSuggestions() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取当前性能指标
            PerformanceOptimizer.PerformanceMetrics metrics = performanceOptimizer.getCurrentPerformanceMetrics();
            
            // 生成优化建议
            java.util.List<PerformanceOptimizer.OptimizationSuggestion> suggestions = 
                performanceOptimizer.analyzePerformanceAndGenerateSuggestions(metrics);
            
            result.put("success", true);
            result.put("metrics", metrics);
            result.put("suggestions", suggestions);
            result.put("suggestionCount", suggestions.size());
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取优化建议失败: " + e.getMessage());
            result.put("timestamp", System.currentTimeMillis());
        }
        
        return result;
    }

    /**
     * 压力测试配置请求类
     */
    public static class StressTestRequest {
        private int threadCount = 10;
        private int durationSeconds = 60;
        private int maxMessagesPerThread = 1000;
        private int messagesPerSecond = 100;
        private int timeoutSeconds = 120;

        // Getter和Setter方法
        public int getThreadCount() { return threadCount; }
        public void setThreadCount(int threadCount) { this.threadCount = threadCount; }
        
        public int getDurationSeconds() { return durationSeconds; }
        public void setDurationSeconds(int durationSeconds) { this.durationSeconds = durationSeconds; }
        
        public int getMaxMessagesPerThread() { return maxMessagesPerThread; }
        public void setMaxMessagesPerThread(int maxMessagesPerThread) { this.maxMessagesPerThread = maxMessagesPerThread; }
        
        public int getMessagesPerSecond() { return messagesPerSecond; }
        public void setMessagesPerSecond(int messagesPerSecond) { this.messagesPerSecond = messagesPerSecond; }
        
        public int getTimeoutSeconds() { return timeoutSeconds; }
        public void setTimeoutSeconds(int timeoutSeconds) { this.timeoutSeconds = timeoutSeconds; }
    }

    /**
     * 基准测试配置请求类
     */
    public static class BenchmarkTestRequest {
        private String benchmarkName = "default-benchmark";
        private int threadCount = 10;
        private int durationSeconds = 60;
        private int maxMessagesPerThread = 1000;
        private int messagesPerSecond = 100;
        private int timeoutSeconds = 120;

        // Getter和Setter方法
        public String getBenchmarkName() { return benchmarkName; }
        public void setBenchmarkName(String benchmarkName) { this.benchmarkName = benchmarkName; }
        
        public int getThreadCount() { return threadCount; }
        public void setThreadCount(int threadCount) { this.threadCount = threadCount; }
        
        public int getDurationSeconds() { return durationSeconds; }
        public void setDurationSeconds(int durationSeconds) { this.durationSeconds = durationSeconds; }
        
        public int getMaxMessagesPerThread() { return maxMessagesPerThread; }
        public void setMaxMessagesPerThread(int maxMessagesPerThread) { this.maxMessagesPerThread = maxMessagesPerThread; }
        
        public int getMessagesPerSecond() { return messagesPerSecond; }
        public void setMessagesPerSecond(int messagesPerSecond) { this.messagesPerSecond = messagesPerSecond; }
        
        public int getTimeoutSeconds() { return timeoutSeconds; }
        public void setTimeoutSeconds(int timeoutSeconds) { this.timeoutSeconds = timeoutSeconds; }
    }
}
